package com.mvc.rpc.feign;

import feign.Client;
import feign.Logger;
import feign.codec.ErrorDecoder;
import feign.okhttp.OkHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * meta feign 默认配置
 * @author JayEinstein
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(RemoteProcedureCallFeign.class)
public class MetaFeignAutoConfiguration {

    @Bean
    @ConditionalOnProperty(value = "feign.hystrix.enabled", havingValue = "false")
    @ConditionalOnMissingBean(Client.class)
    public LoadBalancerFeignClient loadBalancerFeignClient(CachingSpringLoadBalancerFactory cachingFactory,
                                                           SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {

        /**
         * 默认的LoadBalance，{@link org.springframework.cloud.openfeign.ribbon.OkHttpFeignLoadBalancedConfiguration}
         */

        OkHttpClient delegate = new OkHttpClient(okHttpClient);
        return new FallbackLoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
    }

    /**
     * 日志级别
     * @return
     */
    @Bean
    public Logger.Level feignLogLevel() {
        return Logger.Level.FULL;
    }

    /**
     * 错误解析
     * @return
     */
    @Bean
    public ErrorDecoder errorDecoder() {
        return new FeignErrorDecoder();
    }

    /**
     * 远程fallback
     * @return
     */
    @Bean
    @ConditionalOnProperty("feign.hystrix.enabled")
    public RemoteProcedureCallFallback remoteProcedureCallFallback() {
        return new RemoteProcedureCallFallback();
    }

}
